package com.whut.userservice.service.impl;

import cn.hutool.crypto.digest.HMac;
import cn.hutool.crypto.digest.HmacAlgorithm;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.whut.clcommon.exception.BadRequestException;
import com.whut.clcommon.exception.DbException;
import com.whut.clcommon.exception.ForbiddenException;
import com.whut.clcommon.utils.UserContext;
import com.whut.userservice.config.JwtProperties;
import com.whut.userservice.domain.dto.RegisterDTO;
import com.whut.userservice.domain.dto.UpdateUserDTO;
import com.whut.userservice.domain.dto.UserLoginDTO;
import com.whut.userservice.domain.po.User;
import com.whut.userservice.domain.po.UserAttention;
import com.whut.userservice.domain.po.UserFollowInfo;
import com.whut.userservice.domain.vo.UserVO;
import com.whut.userservice.enums.Gender;
import com.whut.userservice.enums.UserStatus;
import com.whut.userservice.mapper.UserMapper;
import com.whut.userservice.service.IUserAttentionService;
import com.whut.userservice.service.IUserFollowInfoService;
import com.whut.userservice.service.IUserService;
import com.whut.userservice.utils.JwtTool;
import jakarta.annotation.Resource;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.time.LocalDate;

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    @Resource
    private JwtTool jwtTool;

    @Resource
    private JwtProperties jwtProperties;

    @Resource
    private IUserFollowInfoService userFollowInfoService;

    @Override
    public String login(UserLoginDTO loginFormDTO) {
        // 1.数据校验
        String username = loginFormDTO.getAccount();
        String password = loginFormDTO.getPassword();
        // 2.根据用户名或手机号查询
        User user = lambdaQuery().eq(User::getAccount, username).one();
        Assert.notNull(user, "用户名错误");
        // 3.校验是否禁用
        if (user.getStatus() == UserStatus.FROZEN) {
            throw new ForbiddenException("用户被冻结");
        }
        // 4.校验密码
        HMac md5 = new HMac(HmacAlgorithm.HmacMD5, "whut_cs".getBytes());
        if (!md5.digestHex(password).equals(user.getPassword())) {
            throw new BadRequestException("用户名或密码错误");
        }
        // 5.生成TOKEN并返回
        return jwtTool.createToken(user.getId(), jwtProperties.getTokenTTL());
    }

    @Override
    public void register(RegisterDTO registerDTO) {
        //1.查看两次输入的密码是否一致
        if (!registerDTO.getPassword().equals(registerDTO.getRepeatPassword())) {
            throw new BadRequestException("两次输入的密码不一致");
        }
        //2.查看该account是否已经被注册
        User user = lambdaQuery().eq(User::getAccount, registerDTO.getAccount()).one();
        if (user != null) {
            throw new BadRequestException("该用户名已存在");
        }
        //3.构造一个user
        user = new User();
        user.setAccount(registerDTO.getAccount());
        HMac md5 = new HMac(HmacAlgorithm.HmacMD5, "whut_cs".getBytes());
        user.setPassword(md5.digestHex(registerDTO.getPassword()));
        //为新注册的用户设置默认头像
        user.setUserAvatar("https://clash-link-user-avatar.oss-cn-hangzhou.aliyuncs.com/f1eb8be0-1d21-4c5c-af8e-bce1f6f0bd3f.png");
        user.setBackgroundImage("https://clash-link-user-avatar.oss-cn-hangzhou.aliyuncs.com/fa1a653d-5664-44c1-9c0b-4aea27d56917.png");
        user.setUserProfile("萌新一枚，还来不及自我介绍");
        user.setNickname(
                jwtTool.createToken(System.currentTimeMillis(), jwtProperties.getTokenTTL())
                       .substring(0,15));
        user.setStatus(UserStatus.NORMAL);
        //4.向user表插入数据
        this.save(user);

        //5.向user_follow_info表插入数据
        UserFollowInfo userFollowInfo = new UserFollowInfo();
        userFollowInfo.setUserId(user.getId());
        userFollowInfo.setAttentionCount(0L);
        userFollowInfo.setFansCount(0L);
        userFollowInfoService.save(userFollowInfo);
    }

    @Override
    public UserVO modify(UpdateUserDTO updateUserDTO) {
        // 1. 获取用户ID并查询用户
        Long id = updateUserDTO.getId();
        // 只能更新自己的信息
        if (!id.equals(UserContext.getUser())) {
            throw new BadRequestException("无权限修改该用户信息");
        }
        User user = this.getById(id);
        if (user == null) {
            throw new BadRequestException("用户不存在");
        }

        // 2. 处理密码更新
        String password = updateUserDTO.getPassword();
        String repeatPassword = updateUserDTO.getRepeatPassword();
        if (password != null && repeatPassword != null && password.equals(repeatPassword)) {
            HMac md5 = new HMac(HmacAlgorithm.HmacMD5);
            user.setPassword(md5.digestHex(password));
        } else if (password != null || repeatPassword != null) {
            throw new BadRequestException("密码和确认密码不一致");
        }

        // 3. 处理头像更新
        String userAvatar = updateUserDTO.getUserAvatar();
        if (userAvatar != null && !userAvatar.isEmpty()) {
            user.setUserAvatar(userAvatar);
        }
        //  4. 处理背景图片更新
        String backgroundImage = updateUserDTO.getBackgroundImage();
        if (backgroundImage != null && !backgroundImage.isEmpty()) {
            user.setBackgroundImage(backgroundImage);
        }

        // 4. 更新其他字段
        String email = updateUserDTO.getEmail();
        if (email != null) {
            user.setEmail(email);
        }
        String nickname = updateUserDTO.getNickname();
        if (nickname != null) {
            user.setNickname(nickname);
        }
        String userProfile = updateUserDTO.getUserProfile();
        if (userProfile != null) {
            user.setUserProfile(userProfile);
        }
        Integer gender = updateUserDTO.getGender();
        if (gender != null) {
            user.setGender(Gender.of(gender));
        }
        LocalDate birthday = updateUserDTO.getBirthday();
        if (birthday != null) {
            user.setBirthday(birthday);
        }

        // 5. 保存更新
        this.updateById(user);

        // 6. 封装VO返回
        UserVO vo = new UserVO();
        BeanUtils.copyProperties(user, vo);
        return vo;
    }




}
